var Server = function()
{
};
//Server.url = "http://localhost/~james/riskcuhk/logic.php";
Server.url = "../logic.php";

var AttackMessage = function()
{
	this.from 	= null;
	this.to		= null;
};
AttackMessage.from 	= null;
AttackMessage.to	= null;
AttackMessage.source = 0;
AttackMessage.clean = function()
{
	AttackMessage.from = null;
	AttackMessage.to	= null;
}

var GameStatus = {
	START: 		"START",
	DEPLOYMENT: "DEPLOYMENT",
	POST: "POST_DEPLOYMENT",
	PLANNING: "ENGAGEMENT_PLANNING",
	ATTACK: "ENGAGEMENT_ATTACK",
	MOBILIZE: "ENGAGEMENT_MOBILIZE",
	END		: "END",
};
var PlayerStatus = {
	END			: "END",
	AFTERATTACK	: "AfterAttack",
	LOADING: "Loading",
	READY:	"Ready",
	PLACEARMY: "PlaceArmy",
	ATTACK: "Attack",
	WATCHING: "Watching",
	REINFORCE: "Reinforce"
};
var PlayerModel = function(user_info)
{
	this.numberOfLands = 0;
	this.ownedLands	= [];

	this.card_number = user_info.card_number;
	this.room_id 	 = user_info.room_id;
	this.session_key = user_info.session_key;
	this.status		 = user_info.status;
	this.troops		 = user_info.troops;
	this.troops_left = user_info.troops_left;
	this.turn		 = user_info.turn;
	this.username 	 = user_info.username;
};

var RiskModel = function()
{
	this.player 		= {};
	this.player.all 	= [];
	this.gameStatus		= "";

};

RiskModel.prototype = {

};

var RiskController = function(model, view)
{
	this.model 	= model;
	this.view	= view;
	this.modelOfView = {};
	this.viewOfModel = {};

	this.viewOfModel.player = {};
	this.viewOfModel.player.all = this.view.playerStatusDiv;
	//this.modelOfView.playerStatusDiv = this.model.player.all;

	this.init();
};

RiskController.prototype = {
	addArmy: function(area)
	{
		$(area).data("map_info").troops += 1;
		console.debug("| $(area).data('map_info')");
		console.debug($(area).data("map_info"));
		this.sendPlaced(area.title);

	},
	init: function()
	{
		var that = this;
		console.debug("| init controller: this.view.areas");
		//console.debug(this.view.areas);

		for (var i = 0; i < this.view.areas.length; i++)
		{
			var area = this.view.areas[i];
			var buttonDiv = area.title.replace(/ /ig, "_");
			area.id		= buttonDiv + "_base";
			area.title = buttonDiv;
			if (area.title.search('Div') == -1)
			{


				//var data = $(area).data;

				buttonDiv	= "Div_" + buttonDiv;
				$(area).data("map_info", {
					buttonDiv: buttonDiv,
					index: i,
					troops: 0,
					continent: '',
					toponym: area.title,
					owner: 0
				});

			$(area).bind("click", function(e){
				//console.debug(e.currentTarget.id);

				var area = e.currentTarget;
				that.clickedOnArea(area);
			});


		}
		else
		{

			var _this = this;
			var str = area + " ";

			var pattern = /^\d+/;
			pattern = /^\d+,\d+/;
			var size = area.coords.match(pattern).toString().split(',');

			var offsetTop = $('#index').offset().top + parseInt(size[1]);
			var offsetLeft = $('#index').offset().left + parseInt(size[0]);

			var div = $('<div>');
			div.css("display", "block")
			.css("position", "absolute")
			.css("left", offsetLeft)
			.css("top", offsetTop)
			.css("width", 32)
			.css("height", 32)
			.css("backgroundRepeat","no-repeat")
			.css("background-align","center")
			.css("line-height","32px")
			.css("text-align","center")
			//.css("background-color","black")
			div.attr('id', area.title);


			div.click( function(e)
			{
				//_this.clickParent(e);
				e.preventDefault();
				var baseId = e.currentTarget.id + "_base";
				baseId = baseId.substring(4);
				var area = document.getElementById(baseId);

				_this.clickedOnArea(area);
				
				//$('#myStatusDiv').html(baseId);
				//$('#' + baseId + '_base').trigger("click");
				//_this.addArmy($('#'+baseId+'_base'));
				console.debug( baseId + " should have clicked");
			});

			div.hover(
				function(e)
				{
					//_this.hoverInParent(e);
					var baseId = e.currentTarget.id + "_base";
					baseId = baseId.substring(4);
					//var area = document.getElementById(baseId);
					$('#' + baseId).mouseover();
					//console.debug("baseId " + baseId);
				},
				function(e)
				{
					//_this.hoverOutParent(e);
					var baseId = e.target.id + "_base";
					baseId = baseId.substring(4);
					$('#' + baseId).mouseout();
					//console.debug("baseId " + baseId);
				}
			);

			div.appendTo($('#armyDiv'));


		}
	}


},
clickedOnArea : function(area)
{
	var that = this;
	var playerState = that.model.player.you.playerState;

	//stopTimer();
	//console.debug(that.model.player.you);
	//alert(that.model.player.you);
	if (playerState == PlayerStatus.PLACEARMY)
	{
		that.addArmy(area);
	} 
	else if (playerState == PlayerStatus.REINFORCE)
	{
		console.debug("Please reinforce");
		that.sendPlaced(area.title);
	}
	else if (playerState == PlayerStatus.WATCHING)
	{
		console.debug("you should be watching and do nothing");
	}
	else if (playerState == PlayerStatus.ATTACK || playerState == PlayerStatus.AFTERATTACK)
	{
		var html = "";

		var buttonDiv = area.title.replace(/ /ig, "_");
		buttonDiv	= "Div_" + buttonDiv;

		if ( ! AttackMessage.from)
		{
			AttackMessage.from = area.title;
      console.debug("button Div: " + buttonDiv);
			$("#" + buttonDiv).attr("class", "attackFrom");
      checkAttackFrom();
		}
		else if ( AttackMessage.from == area.title)
		{
			AttackMessage.from = null;
			AttackMessage.to = null;
			$(area).attr("class", " ");
			//$("#Div_" + AttackMessage.from).attr("class", "");
		}
		else 
		{
			AttackMessage.to	= area.title;	
			$("#" + buttonDiv).attr("class", "attackTo");
      checkAttackTo();
			var tempStatus = that.model.shouldMobilize ? "mobilize":"attack";
			//	var tempStatus = "attack";
			var data = {from: AttackMessage.from,
				to: AttackMessage.to,
				status: tempStatus,
				units: 1
			};

			console.debug("| sendMessage.data");
			console.debug(data);
			//alert();

			that.sendMessage(data);
		}
		//that.view.updateMessageBox();
		that.view.messageBox.update(that);

	}
	else 
	{
		console.debug("unknown phase: " + playerState);
	}
},
sendReady : function()
{
	var that = this;
	var data = "name=player1";
	data += "&status=ready";
	data += "&action=execute&json=1";

	var url = Server.url;

	console.debug(url+"?"+data);;

	$.ajax({
		url: url,
		data: data,
		dataType: 'json',
		success: function(data, status) { that.returnJSONHandler(data, status) },
		error: function(data) { that.errorHandler(data) }
	});
},
sendPlaced : function(toponym)
{
	var that = this;

	//var div = this.view.playerStatusDiv;
	var you = this.model.player.you;
	var gameState = this.model.player.you.status;

	var data = "name=" + you.username;
	if (gameState == "DEPLOYMENT" || gameState == "")
	data += "&deploy_on=" + toponym;
	else data += "&reinforce=" + toponym;
	data += "&action=execute&json=1";

	var url = Server.url;

	console.debug(url+"?"+data);;

	$.ajax({
		url: url,
		data: data,
		dataType: 'json',
	success: function(data, status) { that.returnJSONHandler(data, status) },
	error: function(data) { that.errorHandler(data) }
	});
},
sendCardMessage: function(data, context, callback)
{
	var that = this;

	if ( ! context)
	{
		context = $('#cardDiv');
	}

	if ( ! callback)
	{
		callback = function(data)
		{
			data = eval('(' + data + ')');
			///console.debug(data);
			for (var i in data)
{
			console.debug(data[i]);
}
			this.html(data);
		};
	}
	
	send = {
		url: Server.url,
		success: callback,
		context: context,
		data: data,
	};
	$.ajax(send);		
		
},
sendCustomMessage: function(data)
{
	var that = this;

	data.url = Server.url;
	$.ajax(data);
},
sendMessage: function(data)
{
	var that = this;

	console.debug("| data");
	console.debug(data);

	//alert();
	var url = Server.url;
	$.ajax({
		url:url,
		data: data,
		dataType: 'json',
	success: function(data, status) { that.returnJSONHandler(data, status) },
	error: function(data) { that.errorHandler(data) }
});
},
errorHandler : function(data)
{
	console.debug("errorHandler()");
	console.debug(data);
	alert(data.toString());
},
prepareForMessageBoxUpdate: function()
{
	var gameStatus = this.model.gameStatus;
	var you			= this.model.player.you;
	var messageBox  = this.view.messageBox;

	html = '';
	if (gameStatus == GameStatus.START)
	{
		messageBox.gameStatus(gameStatus, "The game has started");
	}
	else if (gameStatus == GameStatus.DEPLOYMENT)
	{
		messageBox.gameStatus(gameStatus, "Please choose an empty land one by one, you still have " + you.troops_left + " left");
	}
	else if (gameStatus == GameStatus.POST)
	{
		messageBox.gameStatus(gameStatus, "Please add troops to the land you owned, you still have " + you.troops_left + " left");
	}
	else if (gameStatus == GameStatus.PLANNING)
	{
		messageBox.gameStatus(gameStatus, "You've got some new armys, Please add troops to the land you like, you still have " + you.troops_left + " left");
	}
	else if (gameStatus == GameStatus.ATTACK)
	{
		if (this.model.shouldMobilize)
		{
			messageBox.gameStatus(gameStatus, "You've conquered a land! You have to send some troops to the target land!");
			html = "<table><tr><td>from:</td><td>" + AttackMessage.from + "</td></tr>";
			html += "<tr><td>to:</td><td>" + AttackMessage.to + "</td></tr>";
			html += "<tr><td colspan=2><input type='button' value='Continue attack others' onclick=\"riskController.sendMessage({end_mobilize: 1});AttackMessage.clean()\"/></td></table>";
		}
		else 
		{
			messageBox.gameStatus(gameStatus, "Let's Attack! Select one of your owned land and target an enemy land!");
			html = "<table><tr><td>from:</td><td>" + AttackMessage.from + "</td></tr>";
			html += "<tr><td>to:</td><td>" + AttackMessage.to + "</td></tr>";
			html += "<tr><td colspan=2><input type='button' value='Go to Fortify' onclick=\"riskController.sendMessage({end_attack: 1});AttackMessage.clean()\"/></td></table>";
		}
		messageBox.gameControl(html);
	}
	else if (gameStatus == GameStatus.MOBILIZE)
	{
		messageBox.gameStatus(gameStatus, "You've to move some of you troops to the cnquered area");
		html = "<table><tr><td>from:</td><td>" + AttackMessage.from + "</td></tr>";
		html += "<tr><td>to:</td><td>" + AttackMessage.to + "</td></tr>";
		html += "<tr><td colspan=2><input type='button' value='End Mobilizing' onclick=\"riskController.sendMessage({end_mobilize: 1});AttackMessage.clean()\"/></td></table>";
		messageBox.gameControl(html);
	}
	else if (gameStatus == GameStatus.END)
	{
		messageBox.gameStatus(gameStatus, "You've got some new armys, Please add troops to the land you like");
	}
	else if (gameStatus == GameStatus.WAIT_FOR_USING_CARD)
	{
		messageBox.gameStatus(gameStatus, "You've meet the limit of 5 cards, you have to exchange for bonus armies.");
		alert("unknown gameStatus: " + gameStatus);
	}

},

returnJSONHandler : function(data, status)
{
	var that = this;
	returnedJSON = data;

	if (data)
	{
		//console.debug(data);
		this.playerStatusHandler(data.user_info);
		this.mapStatusHandler(data.map_status);
		this.playerDetailsUpdate(data.map_status);
		var html = "<a onclick=\"console.debug(returnedJSON);alert()\">userInfo</a>";
		html += "<br><a onclick=\"console.debug(riskController.model);alert()\">model</a>";
		html += "<br><a onclick=\"console.debug(riskController.view);alert()\">view</a>";
		this.view.userInfo.html(html);


		this.view.messageBox.update(this);


	}

	if (this.model.player.you.status == PlayerStatus.END)
	{
		var message = this.model.player.turn != -1 ? "You win" : "You Lose";
		alert(message);
	}
	else {


		try
		{
			if (this.model.player.you.turn != 1 && hasTimerRunning == 0)
			{
				throw new Exception();
			}

		} catch (e)
		{
			hasTimerRunning++;
			setTimeout(
					function(that)
					{ riskController.sendReady()
					hasTimerRunning--;
					},
					refreshTime);
			console.debug("will resend ready message in " + refreshTime + "  millisecs");
		}
	}

	//if (AttackMessage.from && AttackMessage.to)
	//AttackMessage.clean();
},
playerDetailsUpdate: function(map_status)					
{
	console.debug("-------- playerDetailsUpdate --------");
	var div = this.viewOfModel.player.all;
	//console.debug("| playerStatusDiv");
	//console.debug($(div).data());
	for (var key in map_status)
	{
		var map = map_status[key];
		//console.debug(map.owner);
		//var player = $(div).data()[map.owner-1];
		//console.debug(player);
		if ( map.owner > 0 )
		{
			//var player = this.model.player.all[map.owner - 1];
			var player; //= this.model.player.all[map.owner - 1];
			var index;
			for (var i = 0; i < this.model.player.all.length; i++)
			{
				var temp = this.model.player.all[i];
				if (temp.session_key == map.owner)
				{
					player = temp;
					map.playerIndex = index;
					break;
				}
			}
			//console.debug("| this.model.player.all[%i]", map.owner - 1);
			//console.debug(player);
			player.numberOfLands += 1;
			player.ownedLands.push(map.toponym);
			//console.debug(" > %s %s ownes %s", map.owner, player.username, map.toponym);

		}
	}

	this.view.updatePlayerStatus(this.model.player.all);

	console.debug("+++++++++ end playerDetailsUpdate ++++++++++");
},
getPlayerId: function(session_key)
{
	for (var i = 0; i < returnedJSON.user_info.length; i++)
	{
		var player = returnedJSON.user_info[i];

		if (player.session_key == session_key)
			return i;
		
		}

	return 0;
},
mapStatusHandler : function(map_status)	   
{
	console.debug("mapStatusHandler");
  /**** Clear animation ****/
  //$("#attackFrom").css("visibility","hidden");
  //$("#attackTo").css("visibility","hidden");
  /********/
	var areas = this.view.areas;
	for (var key in map_status)
	{
		var map = map_status[key];
		for (var i = 0; i < areas.length; i++)
		{
			var area = areas[i];

			if (map.toponym == area.title) // if the map is in the returned array
			{
				var buttonDiv = area.title.replace(/ /ig, "_");
				buttonDiv	= "Div_" + buttonDiv;
				
				var playerId = this.getPlayerId(map.owner);
				$(area).data("map_info", {
					continent: 	map.continent,
					//owner:		map.owner,
					//username:	
					playerId: playerId,
					owner:		map.owner,
					toponym:	map.toponym,
					troops:		map.troops,
					buttonDiv: 	buttonDiv	
				});
				var info = $(area).data("map_info");
				//console.debug(" updated '%s' -> troops: %s", area.title, info.troops);

				try {
					var owner = $(area).data("map_info").playerId;
					//console.debug("+++++++++++++++++map");
					//console.debug($(area).data("map_info"));

					showArmy(buttonDiv,owner,info.troops);
				} catch (e){console.debug(e);}

				if (map.battle_flag == 2) // show add army 
				{
					if (map.identity == 1)
					{
						//AttackMessage.source = info.troops;
						AttackMessage.from = area.title;
						$("#"+buttonDiv).attr("class", "mobilizeFrom");
					}
					else
					{
						AttackMessage.to = area.title;
						//AttackMessage.destination = area.troops;
						$("#"+buttonDiv).attr("class", "mobilizeTo");
					}

					this.model.shouldMobilize = 1;



				}
				else if (map.battle_flag == 1)
				{
					if (map.identity == 1){
						$("#"+buttonDiv).attr("class", "attackFrom");
            checkAttackFrom();
          }
					else{ 
						$("#"+buttonDiv).attr("class", "attackTo");
            checkAttackTo();
          }

/*
					$("#"+buttonDiv).animate({
						width:'40px',height:'40px',
					}, 3000, function() {
						$("#"+buttonDiv).animate({
							width:'32px',height:'32px',
					}, 3000, function() {
// Animation complete.
*/
					//});
					//});
				}else{
          $("#"+buttonDiv).attr("class"," ");
        }

			}

		}
	}
	console.debug("end mapStatusHandler");
},
	playerStatusHandler: function(user_info)
	{
		console.debug("playerStatusHandler");
		//	var div = this.view.playerStatusDiv;
		//	$(div).data(user_info);

		this.model.player.you 		= {};
		this.model.player.all 		= [];
		this.model.shouldMobilize	= 0;

		this.model.gameStatus = user_info[0].status;
		//alert(this.model.gameStatus);

		var html = "";
		for (var key in user_info)
		{
			var updated = user_info[key];
			//var player = $(div).data()[key];
			var player = new PlayerModel(user_info[key]);

			//console.debug("| Player %s %s", key, player.username);
			//console.debug(player);

			// set custom variable for state control
			player.isYou = readCookie("session_key") == player.session_key ? 1 : 0;
			//		player.numberOfLands = 0;
			//		player.ownedLands	= [];
			if (updated.status == GameStatus.START)
			{
				if (player.ready == 0)
					player.playerState = PlayerStatus.LOADING;
				else 
					player.playerState = PlayerStatus.READY;
			}
			else if (updated.turn == 0)
			{
				player.playerState = PlayerStatus.WATCHING;
				//AttackMessage.clean();
			}

			if (updated.turn == 1)
			{
				if (updated.status == GameStatus.DEPLOYMENT)
				{
					player.playerState = PlayerStatus.PLACEARMY;
				}
				else if (updated.status == GameStatus.PLANNING)
				{
					player.playerState = PlayerStatus.PLACEARMY;
				}
				else if (updated.status == GameStatus.ATTACK)
				{
					player.playerState = PlayerStatus.ATTACK;
					
					/*
					var map_status = returnedJSON.map_status;
					var areas = this.view.areas;
					for (var key in map_status)
					{
						var map = map_status[key];
						for (var i = 0; i < areas.length; i++)
						{
							if (map.battle_flag == "2")
							{
								player.playerState = PlayerStatus.AFTERATTACK;
								break;
							}
						}
						}*/

				}
				else if (updated.status == GameStatus.MOBILIZE)
				{
					player.playerState = PlayerStatus.ATTACK;
				}
				else if (updated.status == GameStatus.POST)
				{
					player.playerState = PlayerStatus.REINFORCE;
				}
				else player.playerState = PlayerStatus.WATCHING;
			}
			this.model.player.all.push(player);
			if (player.isYou)
			{
				this.model.player.you = this.model.player.all[key];
			}
		}

		//console.debug(" update background");
		if (this.model.player.you.turn == 1 )
		{
			$('body').css("background-color", "yellow");
		}
		else 
		$('body').css("background-color", "white");


		console.debug("end playerStatusHandler");
	}




};


var returnedJSON = null;
var hasTimerRunning = 0;
var riskController;
window.onload = function()
{
	//var img = window.document.getElementById('index');
	//img.className = "mapper noborder";

	var riskModel = new RiskModel();
	var riskView  = new RiskView(
		{
			imgDiv: $('#index'),
			coveringDiv: $('#coveringDiv'),
			map: $('#m_map'),
			areas: $('#m_map > area'),
			playerStatusDiv: $('#playerStatusDiv'),
			messageBox: new MessageBox(document.getElementById('messageBox')),
			userInfo: $('#userInfo'),
	});
	riskController = new RiskController(riskModel, riskView);

	riskController.sendReady();


	$('body').mousemove(function(event)
	{
		var msg = '<table><tr>';
		msg += '<td colspan=2>Handler for .mousemove() called at ' + event.pageX + ', ' + event.pageY + '</td></tr>';

		msg += "<tr><td>target</td><td>" + event.target + "</td></tr>";
		try {
		msg += "<tr><td>from</td><td>" + event.fromElement.id + "</td></tr>";
		}catch(e){}
		msg += "<tr><td>id</td><td>" + event.target.id + "</td></tr>";
		msg += "<tr><td>className</td><td>" + event.target.className + "</td></tr>";
		msg += "<tr><td>index</td><td>" + $('area').index(event.target) + "</td></tr>";
		msg += "</table>";
		$('#eClient').html(msg);
		//
		//event.stopImmediatePropagation();
	});

	/*
	 $('area').mousemove(function(event)
	 {
		 console.debug("area mousemove");
		 event.stopImmediatePropagation();
	 });
	 */

};

var startTimer = function()
{
	console.debug("Starting timer");
	hasTimerRunning  = 0;
	riskController.sendReady();
};

var stopTimer = function()
{
	console.debug("Stopping timer");
	hasTimerRunning = 20;
}
